Android14 Surface 同步机制 SurfaceSyncGroup 实现分析

10/30/2024

# 1. 初步认识 SurfaceSyncGroup

注释中对 SurfaceSyncGroup 的描述是:

A way for data to be gathered so multiple surfaces can be synced. This is intended to be used with AttachedSurfaceControl, SurfaceView, and SurfaceControlViewHost. This allows different parts of the system to synchronize different surfaces themselves without having to manage timing of different rendering threads. This will also allow synchronization of surfaces across multiple processes. The caller can add SurfaceControlViewHosts from another process to the SurfaceSyncGroup in a different process and this clas will ensure all the surfaces are ready before applying everything together.

翻译一下:

一种收集数据的方法,以便多个 Surface 可以同步。该方法旨在与 AttachedSurfaceControl、SurfaceView 和 SurfaceControlViewHost 一起使用。这使得系统中的不同部分可以自行同步不同的 Surface ,而无需处理不同渲染线程的渲染完成时间的不同导致的问题。这也允许在多个进程之间的 Surface 上使用。调用者可以在另一个进程中添加 SurfaceControlViewHost,并将其添加到不同进程中的 SurfaceSyncGroup 中,该类将确保在将所有内容应用在一起之前所有表面都已就绪。

有一说一,注释确实有点晦涩难懂,能一遍看懂的都是真大佬。

在 Android13 中增加了 Surface 同步机制,主要作用是提供 ViewRootImpl、SurfaceView 和 SurfaceControlViewHost 的渲染同步服务。具体的,在 ViewRootImpl、SurfaceView 和 SurfaceControlViewHost 均完成绘制时再去上报至 WMS 进行窗口状态的切换。避免 ViewRootImpl 绘制完成上报至 WMS 后、同时 SurfaceView/SurfaceControlViewHost 迟迟没有绘制完成使得 startingWindow 过早移除从而产生黑屏/闪屏的现象。

Android13 中 Surface 同步相关的代码主要在 SurfaceSyncer.java,Android14 重构为 SurfaceSyncGroup.java。本文主要分析 Android14 中的实现。

另外,我们主要分析 ViewRootImpl 的同步过程。SurfaceView 和 SurfaceControlViewHost 大体都是类似的。SurfaceControlViewHost 最大的差异是涉及到跨进程通信。

在阅读了相关源码后,总结 SurfaceSyncGroup 有以下一些特点:

  • 每一个 ViewRootImpl/SurfaceView/SurfaceControlViewHost 对象会有一个对应的 SurfaceSyncGroup 对象。
  • 每一个 SurfaceSyncGroup 对象都有一个 mTransactionReadyConsumer 回调,当对应的 ViewRootImpl/SurfaceView/SurfaceControlViewHost 绘制完成后,会调用到该回调
  • 多个 SurfaceSyncGroup 通过树结构组织起来,通过成员 ISurfaceSyncGroup mParentSyncGroup; 可以找到其父节点。ViewRootImpl 中有一个 mWmsRequestSyncGroup 成员是这颗树的根节点
  • 当 SurfaceSyncGroup 节点 A 添加一个子节点 B 时,会将子节点 B 的 ISurfaceSyncGroup mParentSyncGroup; 成员指向父节点 A 的 ISurfaceSyncGroup mISurfaceSyncGroup 成员,mISurfaceSyncGroup 有一个隐式的 this 引用指向 SurfaceSyncGroup 节点 A
  • 当 SurfaceSyncGroup 节点 A 添加一个子节点 B 时
    • 会将节点 A 的 Consumer<Transaction> mTransactionReadyConsumer; 包装成一个 ITransactionReadyCallback 对象,添加到节点 A 的ArraySet<ITransactionReadyCallback> mPendingSyncs 成员中。
    • 同时将该 ITransactionReadyCallback 对象发送给节点 B,节点 B 重新构造自己的 Consumer<Transaction> mTransactionReadyConsumer;
    • 当节点 B 对应的 Surface 绘制完后后,就会调用重新构造的 Consumer<Transaction> mTransactionReadyConsumer; 回调,在该回调中,先调用节点 B 自己原来的 mTransactionReadyConsumer 回调,再调用父节点 A 传过来的 ITransactionReadyCallback,同时将 ITransactionReadyCallback 从父节点 A 的 mPendingSyncs 成员中删除
  • 只有 A 节点中的 mPendingSyncs 为空时,A 节点的子节点们才算都绘制完成了。

整体的结构示意图如下:

20241105201536

原图链接:https://boardmix.cn/app/share/CAE.CMLx1wwgASoQXfKYHfTZha6HKulTcIApEjAGQAE/hxtUlY

接下来,我们就从源码中逐一解析这些特点。

# 2. ViewRootImpl 中的关键流程

App 端添加和显示窗口时,会调用到 ViewRootImpl::performTraversals 方法:

    // ViewRootImpl
    private void performTraversals() {

        // ......

        boolean cancelDueToPreDrawListener = mAttachInfo.mTreeObserver.dispatchOnPreDraw();

        boolean cancelAndRedraw = cancelDueToPreDrawListener
                 || (cancelDraw && mDrewOnceForSync);
        
        if (!cancelAndRedraw) {
            // A sync was already requested before the WMS requested sync. This means we need to
            // sync the buffer, regardless if WMS wants to sync the buffer.
            if (mActiveSurfaceSyncGroup != null) {
                mSyncBuffer = true;
            }

            // 具体分析见第 3 节
            // 初始化 SurfaceSyncGroup 树结构
            createSyncIfNeeded();
            notifyDrawStarted(isInWMSRequestedSync());
            mDrewOnceForSync = true;

            // If the active SSG is also requesting to sync a buffer, the following needs to happen
            // 1. Ensure we keep track of the number of active syncs to know when to disable RT
            //    RT animations that conflict with syncing a buffer.
            // 2. Add a safeguard SSG to prevent multiple SSG that sync buffers from being submitted
            //    out of order.
            if (mActiveSurfaceSyncGroup != null && mSyncBuffer) {
                updateSyncInProgressCount(mActiveSurfaceSyncGroup);
                safeguardOverlappingSyncs(mActiveSurfaceSyncGroup);
            }
        }


        // .......
        
            if (!performDraw() && mActiveSurfaceSyncGroup != null) {
                // 关注点2
                // 绘制完成,通知 SurfaceSyncGroup 开始回调
                mActiveSurfaceSyncGroup.markSyncReady();
            }

        // ......

        if (!cancelAndRedraw) {
            mReportNextDraw = false;
            mLastReportNextDrawReason = null;
            mActiveSurfaceSyncGroup = null;
            mSyncBuffer = false;
            if (isInWMSRequestedSync()) {
                //关注点3  根节点 ready
                mWmsRequestSyncGroup.markSyncReady();
                mWmsRequestSyncGroup = null;
                mWmsRequestSyncGroupState = WMS_SYNC_NONE;
            }
        }        
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  • 关注点1,createSyncIfNeeded,SurfaceSyncGroup 树结构的初始化,在第 3 节分析
  • 关注点2,mActiveSurfaceSyncGroup.markSyncReady(),绘制完成,通知 SurfaceSyncGroup 开始回调,在第 4 节分析
  • 关注点3,mWmsRequestSyncGroup.markSyncReady(),根节点 ready,在第 5 节分析

# 3. createSyncIfNeeded,SurfaceSyncGroup 树结构的初始化

createSyncIfNeeded 的实现如下:

// ViewRootImpl

    // 根节点 SurfaceSyncGroup
    private SurfaceSyncGroup mWmsRequestSyncGroup;
    // ViewRootImpl 对应的 SurfaceSyncGroup
    private SurfaceSyncGroup mActiveSurfaceSyncGroup;

    // mWmsRequestSyncGroup 的状态,有三个值 WMS_SYNC_NONE,WMS_SYNC_PENDING,WMS_SYNC_MERGED
    int mWmsRequestSyncGroupState; 

    private void createSyncIfNeeded() {
        // WMS requested sync already started or there's nothing needing to sync
        if (isInWMSRequestedSync() || !mReportNextDraw) {
            return;
        }

        final int seqId = mSyncSeqId;
        // 状态设置为 WMS_SYNC_PENDING
        mWmsRequestSyncGroupState = WMS_SYNC_PENDING;
        // 关注点1
        // 初始化树的根节点
        // 传入的回调中会调用 reportDrawFinished 通知 WMS,App 这边绘制好了,可以显示图层了
        mWmsRequestSyncGroup = new SurfaceSyncGroup("wmsSync-" + mTag, t -> {
            mWmsRequestSyncGroupState = WMS_SYNC_MERGED;
            // 远程调用 wms ,通知 wms 可以显示图层了
            reportDrawFinished(t, seqId);
        });
        if (DEBUG_BLAST) {
            Log.d(mTag, "Setup new sync=" + mWmsRequestSyncGroup.getName());
        }

        // 关注点2
        // SurfaceSyncGroup 链表添加 ViewRootImpl 对应的 SurfaceSyncGroup
        mWmsRequestSyncGroup.add(this, null /* runnable */);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  • 关注点1,初始化 SurfaceSyncGroup 树的根节点 ViewRootImpl::mWmsRequestSyncGroup
  • 关注点2,将 ViewRootImpl 添加到 SurfaceSyncGroup 树中

关注点1,new 了一个 SurfaceSyncGroup 对象,对应的构造函数事项如下:

// SurfaceSyncGroup

    // 重要回调成员
    private Consumer<Transaction> mTransactionReadyConsumer;

    public SurfaceSyncGroup(String name, Consumer<Transaction> transactionReadyConsumer) {
        
        if (sCounter.get() >= MAX_COUNT) {
            sCounter.set(0);
        }

        mName = name + "#" + sCounter.getAndIncrement();
        mTrackName = "SurfaceSyncGroup " + name;

        // 重要成员初始化
        mTransactionReadyConsumer = (transaction) -> {
            if (DEBUG && transaction != null) {
                Log.d(TAG, "Sending non null transaction " + transaction + " to callback for "
                        + mName);
            }
            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName,
                        "Final TransactionCallback with " + transaction);
            }
            Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_VIEW, mTrackName, hashCode());
            //调用传入的回调
            transactionReadyConsumer.accept(transaction);
            synchronized (mLock) {
                // If there's a registered listener with WMS, that means we aren't actually complete
                // until WMS notifies us that the parent has completed.
                if (mSurfaceSyncGroupCompletedListener == null) { //调用同步完成回调
                    invokeSyncCompleteCallbacks(); // 调用 mSyncCompleteCallbacks
                } 
            }
        };

        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_VIEW, mTrackName, mName, hashCode());
        }

        if (DEBUG) {
            Log.d(TAG, "setupSync " + mName + " " + Debug.getCallers(2));
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

构造函数中主要是初始化根节点 mWmsRequestSyncGroup 的成员 mTransactionReadyConsumer 回调。该回调调用了传入的 transactionReadyConsumer 参数。

那什么时候会调用到 mTransactionReadyConsumer 呢?

  • 对于叶子节点的 SurfaceSyncGroup,其对应的 Surface 绘制完成后,就会调用到其 mTransactionReadyConsumer 回调
  • 对于非叶子节点的 SurfaceSyncGroup,其所有子节点对应的 Surface 都绘制完后后,就会调用到其 mTransactionReadyConsumer 回调

关注点2,会初始化一个 ViewRootImpl 对应的 SurfaceSyncGroup 对象 ViewRootImpl::mActiveSurfaceSyncGroup,并将其添加到 SurfaceSyncGroup 树中。

接下来我们来看 SurfaceSyncGroup::add 方法的实现:

// SurfaceSyncGroup

    // attachedSurfaceControl:传入的是 ViewRootImpl 对象,ViewRootImpl 实现了 AttachedSurfaceControl 接口
    @UiThread
    public boolean add(@Nullable AttachedSurfaceControl attachedSurfaceControl,
            @Nullable Runnable runnable) {
        if (attachedSurfaceControl == null) {
            return false;
        }
        // 调用 ViewRootImpl 的 getOrCreateSurfaceSyncGroup
        SurfaceSyncGroup surfaceSyncGroup = attachedSurfaceControl.getOrCreateSurfaceSyncGroup();
        if (surfaceSyncGroup == null) {
            return false;
        }

        return add(surfaceSyncGroup, runnable);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

先调用 ViewRootImpl::getOrCreateSurfaceSyncGroup,然后调用另一个 add 重载:

// ViewRootImpl

    private SurfaceSyncGroup mActiveSurfaceSyncGroup;

    @Override
    public SurfaceSyncGroup getOrCreateSurfaceSyncGroup() {
        boolean newSyncGroup = false;
        if (mActiveSurfaceSyncGroup == null) {
            
            // 初始化 ViewRootImpl 对应的 SurfaceSyncGroup 对象
            mActiveSurfaceSyncGroup = new SurfaceSyncGroup(mTag);

            // 配置 mActiveSurfaceSyncGroup
            mActiveSurfaceSyncGroup.setAddedToSyncListener(() -> {
                Runnable runnable = () -> {
                    // Check if it's already 0 because the timeout could have reset the count to
                    // 0 and we don't want to go negative.
                    if (mNumPausedForSync > 0) {
                        mNumPausedForSync--;
                    }
                    if (mNumPausedForSync == 0) {
                        mHandler.removeMessages(MSG_PAUSED_FOR_SYNC_TIMEOUT);
                        if (!mIsInTraversal) {
                            scheduleTraversals();
                        }
                    }
                };

                if (Thread.currentThread() == mThread) {
                    runnable.run();
                } else {
                    mHandler.post(runnable);
                }
            });
            newSyncGroup = true;
        }

        Trace.instant(Trace.TRACE_TAG_VIEW,
                "getOrCreateSurfaceSyncGroup isNew=" + newSyncGroup + " " + mTag);

        if (DEBUG_BLAST) {
            if (newSyncGroup) {
                Log.d(mTag, "Creating new active sync group " + mActiveSurfaceSyncGroup.getName());
            } else {
                Log.d(mTag, "Return already created active sync group "
                        + mActiveSurfaceSyncGroup.getName());
            }
        }

        mNumPausedForSync++;
        mHandler.removeMessages(MSG_PAUSED_FOR_SYNC_TIMEOUT);
        mHandler.sendEmptyMessageDelayed(MSG_PAUSED_FOR_SYNC_TIMEOUT,
                1000 * Build.HW_TIMEOUT_MULTIPLIER);

        // 返回
        return mActiveSurfaceSyncGroup;
    };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

这里调用了另一个构造方法初始化 mActiveSurfaceSyncGroup 成员,配置后返回。

    public SurfaceSyncGroup(@NonNull String name) {
        this(name, transaction -> {
            if (transaction != null) {
                if (DEBUG) {
                    Log.d(TAG, "Applying transaction " + transaction);
                }
                transaction.apply();
            }
        });
    }
1
2
3
4
5
6
7
8
9
10

这里使用默认的回调,回调中就简单 apply。

接着我们看 add 重载:

// SurfaceSyncGroup

    public boolean add(@NonNull SurfaceSyncGroup surfaceSyncGroup,
            @Nullable Runnable runnable) {
        return add(surfaceSyncGroup.mISurfaceSyncGroup, false /* parentSyncGroupMerge */,
                runnable);
    }
1
2
3
4
5
6
7

这里获取了 SurfaceSyncGroup::mISurfaceSyncGroup 成员。

// SurfaceSyncGroup
    public final ISurfaceSyncGroup mISurfaceSyncGroup = new ISurfaceSyncGroupImpl();
1
2

该成员在定义时,就初始化为 ISurfaceSyncGroupImpl 类型。ISurfaceSyncGroupImpl 是 SurfaceSyncGroup 的非Static的内部类,也就是说存在一个隐式的 this 引用指向外部的 SurfaceSyncGroup 对象。

ISurfaceSyncGroupImpl 的定义如下:

// SurfaceSyncGroup 内部类

    private class ISurfaceSyncGroupImpl extends ISurfaceSyncGroup.Stub {

        @Override
        public boolean onAddedToSyncGroup(IBinder parentSyncGroupToken,
                boolean parentSyncGroupMerge) {
            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_VIEW, mTrackName,
                        "onAddedToSyncGroup token=" + parentSyncGroupToken.hashCode(), hashCode());
            }
            boolean didAdd = addSyncToWm(parentSyncGroupToken, parentSyncGroupMerge, null);
            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_VIEW, mTrackName, hashCode());
            }
            return didAdd;
        }

        @Override
        public boolean addToSync(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge) {
            return SurfaceSyncGroup.this.add(surfaceSyncGroup, parentSyncGroupMerge,
                    null /* runnable */);
        }

        // 获取到外部类对象
        SurfaceSyncGroup getSurfaceSyncGroup() {
            return SurfaceSyncGroup.this;
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

获取到 mISurfaceSyncGroup 后,接着调用另一个 add 重载:

// SurfaceSyncGroup

    public boolean add(ISurfaceSyncGroup surfaceSyncGroup, boolean parentSyncGroupMerge,
            @Nullable Runnable runnable) {
        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_VIEW, mTrackName,
                    "addToSync token=" + mToken.hashCode(), hashCode());
        }
        synchronized (mLock) {
            if (mSyncReady) {
                Log.w(TAG, "Trying to add to sync when already marked as ready " + mName);
                if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                    Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_VIEW, mTrackName, hashCode());
                }
                return false;
            }
        }

        if (runnable != null) {
            runnable.run();
        }

        if (isLocalBinder(surfaceSyncGroup.asBinder())) { //进入
            // 关注点
            boolean didAddLocalSync = addLocalSync(surfaceSyncGroup, parentSyncGroupMerge);
            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_VIEW, mTrackName, hashCode());
            }
            return didAddLocalSync; // 直接返回了
        }
        
        // 后面就不看了
        // ......
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

接着调用 addLocalSync 方法:

// SurfaceSyncGroup

    private boolean addLocalSync(ISurfaceSyncGroup childSyncToken, boolean parentSyncGroupMerge) {
        if (DEBUG) {
            Log.d(TAG, "Adding local sync to " + mName);
        }

        // 通过 this 引用,拿到 ViewRootImpl::mActiveSurfaceSyncGroup
        SurfaceSyncGroup childSurfaceSyncGroup = getSurfaceSyncGroup(childSyncToken);

        if (childSurfaceSyncGroup == null) {
            Log.e(TAG, "Trying to add a local sync that's either not valid or not from the"
                    + " local process=" + childSyncToken);
            return false;
        }

        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_VIEW, mTrackName,
                    "addLocalSync=" + childSurfaceSyncGroup.mName, hashCode());
        }


        // 关注点1
        // 构建当前节点也就是父节点 mWmsRequestSyncGroup 的回调包装
        ITransactionReadyCallback callback =
                createTransactionReadyCallback(parentSyncGroupMerge); //false

        if (callback == null) {
            return false;
        }

        // 关注点2
        // 将子节点插入树中,并传入了父节点 mWmsRequestSyncGroup 的回调包装
        childSurfaceSyncGroup.setTransactionCallbackFromParent(mISurfaceSyncGroup, callback);

        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_VIEW, mTrackName, hashCode());
        }
        return true;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

关注点1,createTransactionReadyCallback 的实现如下:

    public ITransactionReadyCallback createTransactionReadyCallback(boolean parentSyncGroupMerge) {

        if (DEBUG) {
            Log.d(TAG, "createTransactionReadyCallback as part of " + mName);
        }

        // 构建当前回调 mTransactionReadyConsumer 的包装,传递给子节点
        ITransactionReadyCallback transactionReadyCallback =
                new ITransactionReadyCallback.Stub() {
                    @Override
                    public void onTransactionReady(Transaction t) {
                        synchronized (mLock) {
                            if (t != null) {
                                t.sanitize(Binder.getCallingPid(), Binder.getCallingUid());
                                //合并 Transaction
                                if (parentSyncGroupMerge) {
                                    t.merge(mTransaction);
                                }
                                mTransaction.merge(t);
                            }
                            mPendingSyncs.remove(this);
                            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                                Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName,
                                        "onTransactionReady callback=" + hashCode());
                            }
                            checkIfSyncIsComplete(); //回调 mTransactionReadyConsumer
                        } 
                    }
                };

        synchronized (mLock) {
            if (mSyncReady) {
                Log.e(TAG, "Sync " + mName
                        + " was already marked as ready. No more SurfaceSyncGroups can be added.");
                return null;
            }
            // 新构建的 ITransactionReadyCallback 添加到 mPendingSyncs 中
            mPendingSyncs.add(transactionReadyCallback);
            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName,
                        "createTransactionReadyCallback mPendingSyncs="
                                + mPendingSyncs.size() + " transactionReady="
                                + transactionReadyCallback.hashCode());
            }
        }

        // Start the timeout when another SSG has been added to this SurfaceSyncGroup. This is
        // because if the other SurfaceSyncGroup has bugs and doesn't complete, it will affect this
        // SSGs. So it's better to just add a timeout in case the other SSG doesn't invoke the
        // callback and complete this SSG.
        addTimeout();

        return transactionReadyCallback;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

构建了一个 ITransactionReadyCallback 回调,回调中合并了参数 Transaction,将 ITransactionReadyCallback 从 mPendingSyncs 移除,然后调用 checkIfSyncIsComplete。

ITransactionReadyCallback 构建完成后会添加到成员 mPendingSyncs 中去。也就是说,每添加一个子节点 mPendingSyncs 中就会多一个 ITransactionReadyCallback 对象。

接着看 checkIfSyncIsComplete 的实现:

// /frameworks/base/core/java/android/window/SurfaceSyncGroup.java
    private void checkIfSyncIsComplete() {
        if (mFinished) {
            if (DEBUG) {
                Log.d(TAG, "SurfaceSyncGroup=" + mName + " is already complete");
            }
            mTransaction.apply();
            return;
        }

        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName,
                    "checkIfSyncIsComplete mSyncReady=" + mSyncReady
                            + " mPendingSyncs=" + mPendingSyncs.size());
        }

        if (!mSyncReady || !mPendingSyncs.isEmpty()) {  // 没有 ready 的情况
            if (DEBUG) {
                Log.d(TAG, "SurfaceSyncGroup=" + mName + " is not complete. mSyncReady="
                        + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size());
            }
            return;
        }


        // mSyncReady 为 true && mPendingSyncs 不为空,那么同步就完成了。

        if (DEBUG) {
            Log.d(TAG, "Successfully finished sync id=" + mName);
        }
        // 回调 mTransactionReadyConsumer
        mTransactionReadyConsumer.accept(mTransaction);
        mFinished = true;
        if (mTimeoutAdded) {
            mHandler.removeCallbacksAndMessages(this);
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

mSyncReady 为 true && mPendingSyncs 不为空时,表示回调完成了。接着就会调用当前节点的 mTransactionReadyConsumer 回调。

关注点2,接着看 setTransactionCallbackFromParent 的实现:

    // 子节点调用
    private void setTransactionCallbackFromParent(ISurfaceSyncGroup parentSyncGroup,
            ITransactionReadyCallback transactionReadyCallback) {

        if (DEBUG) {
            Log.d(TAG, "setTransactionCallbackFromParent for child " + mName);
        }

        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_VIEW, mTrackName,
                    "setTransactionCallbackFromParent " + mName + " callback="
                            + transactionReadyCallback.hashCode(), hashCode());
        }

        // Start the timeout when this SurfaceSyncGroup has been added to a parent SurfaceSyncGroup.
        // This is because if the other SurfaceSyncGroup has bugs and doesn't complete, this SSG
        // will get stuck. It's better to complete this SSG even if the parent SSG is broken.
        addTimeout();

        boolean finished = false;
        Runnable addedToSyncListener = null;

        synchronized (mLock) {
            if (mFinished) {
                finished = true;
            } else {
                // If this SurfaceSyncGroup was already added to a different SurfaceSyncGroup, we
                // need to combine everything. We can add the old SurfaceSyncGroup parent to the new
                // parent so the new parent doesn't complete until the old parent does.
                // Additionally, the old parent will not get the final transaction object and
                // instead will send it to the new parent, ensuring that any other SurfaceSyncGroups
                // from the original parent are also combined with the new parent SurfaceSyncGroup.


                // 已经有父节点的情况,不进入
                if (mParentSyncGroup != null && mParentSyncGroup != parentSyncGroup) { 
                    if (DEBUG) {
                        Log.d(TAG, "Trying to add to " + parentSyncGroup
                                + " but already part of sync group " + mParentSyncGroup + " "
                                + mName);
                    }
                    try {
                        parentSyncGroup.addToSync(mParentSyncGroup,
                                true /* parentSyncGroupMerge */);
                    } catch (RemoteException e) {
                    }
                }

                if (DEBUG && mParentSyncGroup == parentSyncGroup) {
                    Log.d(TAG, "Added to parent that was already the parent");
                }

            
                Consumer<Transaction> lastCallback = mTransactionReadyConsumer;

                mParentSyncGroup = parentSyncGroup;

                // 重新定义子节点的 mTransactionReadyConsumer 回调
                mTransactionReadyConsumer = (transaction) -> {
                    if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                        Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_VIEW, mTrackName,
                                "Invoke transactionReadyCallback="
                                        + transactionReadyCallback.hashCode(), hashCode());
                    }

                    // 调用自己的 TransactionReadyConsumer
                    lastCallback.accept(null); 

                    try {
                        // 调用父节点的 TransactionReadyConsumer
                        // transactionReadyCallback 通过参数传入
                        transactionReadyCallback.onTransactionReady(transaction);
                    } catch (RemoteException e) {
                        transaction.apply();
                    }
                    if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                        Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_VIEW, mTrackName, hashCode());
                    }
                };

                addedToSyncListener = mAddedToSyncListener;
            }
        }

        // Invoke the callback outside of the lock when the SurfaceSyncGroup being added was already
        // complete.
        if (finished) {
            try {
                transactionReadyCallback.onTransactionReady(null);
            } catch (RemoteException e) {
            }
        } else if (addedToSyncListener != null) {
            addedToSyncListener.run();
        }
        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_VIEW, mTrackName, hashCode());
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

这里使用父节点中重新构建的 ITransactionReadyCallback 对象,重新定义了子节点的 mTransactionReadyConsumer 回调。该回调中会先调用了原来的 mTransactionReadyConsumer 回调,然后调用父节点提供的 ITransactionReadyCallback 回调。

# 4. 绘制完成的回调过程

ViewRootImpl 绘制完成后,就会去调用 mActiveSurfaceSyncGroup.markSyncReady()

    public void markSyncReady() {
        if (DEBUG) {
            Log.d(TAG, "markSyncReady " + mName);
        }
        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName, "markSyncReady");
        }
        synchronized (mLock) {
            if (mHasWMSync) {
                try {
                    WindowManagerGlobal.getWindowManagerService().markSurfaceSyncGroupReady(mToken);
                } catch (RemoteException e) {
                }
            }
            // 修改标志变量,绘制完成了
            mSyncReady = true;
            // 关注点
            checkIfSyncIsComplete();
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

将 mActiveSurfaceSyncGroup 的标志成员 mSyncReady 修改为 true 后调用 checkIfSyncIsComplete() 方法。

    private void checkIfSyncIsComplete() {
        if (mFinished) {
            if (DEBUG) {
                Log.d(TAG, "SurfaceSyncGroup=" + mName + " is already complete");
            }
            mTransaction.apply();
            return;
        }

        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName,
                    "checkIfSyncIsComplete mSyncReady=" + mSyncReady
                            + " mPendingSyncs=" + mPendingSyncs.size());
        }
        // mSyncReady 为 true
        // mPendingSyncs 为 空
        if (!mSyncReady || !mPendingSyncs.isEmpty()) {  // 不进入,
            if (DEBUG) {
                Log.d(TAG, "SurfaceSyncGroup=" + mName + " is not complete. mSyncReady="
                        + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size());
            }
            return;
        }

        if (DEBUG) {
            Log.d(TAG, "Successfully finished sync id=" + mName);
        }
        // 调用回调链
        mTransactionReadyConsumer.accept(mTransaction);
        mFinished = true;
        if (mTimeoutAdded) {
            mHandler.removeCallbacksAndMessages(this);
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

mActiveSurfaceSyncGroup 的 mTransactionReadyConsumer 在 mActiveSurfaceSyncGroup 被添加到树结构时,被重新赋值了,我们再回顾一下:

                // 重新定义子节点的 mTransactionReadyConsumer 回调
                mTransactionReadyConsumer = (transaction) -> {
                    if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                        Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_VIEW, mTrackName,
                                "Invoke transactionReadyCallback="
                                        + transactionReadyCallback.hashCode(), hashCode());
                    }

                    // 调用自己的 TransactionReadyConsumer,null
                    lastCallback.accept(null); 

                    try {
                        // 调用父节点的 TransactionReadyConsumer
                        // transactionReadyCallback 通过参数传入
                        transactionReadyCallback.onTransactionReady(transaction);
                    } catch (RemoteException e) {
                        transaction.apply();
                    }
                    if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                        Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_VIEW, mTrackName, hashCode());
                    }
                };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

先调用 mActiveSurfaceSyncGroup 自己原来的 mTransactionReadyConsumer 回调:

    public SurfaceSyncGroup(@NonNull String name) {
        this(name, transaction -> {
            if (transaction != null) {
                if (DEBUG) {
                    Log.d(TAG, "Applying transaction " + transaction);
                }
                transaction.apply();
            }
        });
    }
1
2
3
4
5
6
7
8
9
10

就是简单 apply transaction。但是传入的参数是 null,所以啥也不干。(为什么是 null ?)

接着会调用父节点 mWmsRequestSyncGroup 的 ITransactionReadyCallback 回调:

        ITransactionReadyCallback transactionReadyCallback =
                new ITransactionReadyCallback.Stub() {
                    @Override
                    public void onTransactionReady(Transaction t) {
                        synchronized (mLock) {
                            if (t != null) {
                                t.sanitize(Binder.getCallingPid(), Binder.getCallingUid());
                                //合并子节点的 Transaction
                                if (parentSyncGroupMerge) {
                                    t.merge(mTransaction);
                                }
                                mTransaction.merge(t);
                            }
                            mPendingSyncs.remove(this);
                            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                                Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName,
                                        "onTransactionReady callback=" + hashCode());
                            }
                            checkIfSyncIsComplete(); //回调 mTransactionReadyConsumer
                        } 
                    }
                };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

这里将子节点的 Transaction 合并以后,接着把 ITransactionReadyCallback 从 mPendingSyncs 中移除,mPendingSyncs 此时为空了。

接着调用 checkIfSyncIsComplete:

    private void checkIfSyncIsComplete() {
        if (mFinished) {
            if (DEBUG) {
                Log.d(TAG, "SurfaceSyncGroup=" + mName + " is already complete");
            }
            mTransaction.apply();
            return;
        }

        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName,
                    "checkIfSyncIsComplete mSyncReady=" + mSyncReady
                            + " mPendingSyncs=" + mPendingSyncs.size());
        }
        // mSyncReady 为 false
        // mPendingSyncs 为 空
        if (!mSyncReady || !mPendingSyncs.isEmpty()) {  // 进入,
            if (DEBUG) {
                Log.d(TAG, "SurfaceSyncGroup=" + mName + " is not complete. mSyncReady="
                        + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size());
            }
            // 直接回了
            return;
        }

        if (DEBUG) {
            Log.d(TAG, "Successfully finished sync id=" + mName);
        }
        mTransactionReadyConsumer.accept(mTransaction);
        mFinished = true;
        if (mTimeoutAdded) {
            mHandler.removeCallbacksAndMessages(this);
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

此时,mSyncReady 为 false,这里会直接返回。

回到 ViewRootImpl::performTraversals 方法中,最后会调用:

        if (!cancelAndRedraw) {
            mReportNextDraw = false;
            mLastReportNextDrawReason = null;
            mActiveSurfaceSyncGroup = null;
            mSyncBuffer = false;
            if (isInWMSRequestedSync()) {
                //关注点3  根节点 ready
                mWmsRequestSyncGroup.markSyncReady();
                mWmsRequestSyncGroup = null;
                mWmsRequestSyncGroupState = WMS_SYNC_NONE;
            }
        }    
1
2
3
4
5
6
7
8
9
10
11
12

就会去调用 mWmsRequestSyncGroup.markSyncReady()

    public void markSyncReady() {
        if (DEBUG) {
            Log.d(TAG, "markSyncReady " + mName);
        }
        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName, "markSyncReady");
        }
        synchronized (mLock) {
            if (mHasWMSync) {
                try {
                    WindowManagerGlobal.getWindowManagerService().markSurfaceSyncGroupReady(mToken);
                } catch (RemoteException e) {
                }
            }
            // 修改标志变量,绘制完成了
            mSyncReady = true;
            // 关注点
            checkIfSyncIsComplete();
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

修改 mSyncReady 为 true 后再次调用 checkIfSyncIsComplete 方法:

    private void checkIfSyncIsComplete() {
        if (mFinished) {
            if (DEBUG) {
                Log.d(TAG, "SurfaceSyncGroup=" + mName + " is already complete");
            }
            mTransaction.apply();
            return;
        }

        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.instantForTrack(Trace.TRACE_TAG_VIEW, mTrackName,
                    "checkIfSyncIsComplete mSyncReady=" + mSyncReady
                            + " mPendingSyncs=" + mPendingSyncs.size());
        }
        // mSyncReady 为 true
        // mPendingSyncs 为 空
        if (!mSyncReady || !mPendingSyncs.isEmpty()) {  // 不进入,
            if (DEBUG) {
                Log.d(TAG, "SurfaceSyncGroup=" + mName + " is not complete. mSyncReady="
                        + mSyncReady + " mPendingSyncs=" + mPendingSyncs.size());
            }
            
            return;
        }

        if (DEBUG) {
            Log.d(TAG, "Successfully finished sync id=" + mName);
        }
        // 调用回调链
        mTransactionReadyConsumer.accept(mTransaction);
        mFinished = true;
        if (mTimeoutAdded) {
            mHandler.removeCallbacksAndMessages(this);
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

接着就会调用到 mWmsRequestSyncGroup 的 mTransactionReadyConsumer 回调。

        mWmsRequestSyncGroup = new SurfaceSyncGroup("wmsSync-" + mTag, t -> {
            mWmsRequestSyncGroupState = WMS_SYNC_MERGED;
            // 远程调用 wms ,通知 wms 可以显示图层了
            reportDrawFinished(t, seqId);
        });
1
2
3
4
5

到这里每个 SurfaceSyncGroup 都调用了 markSyncReady 方法,表示 Surface 都绘制完了,接着调用 reportDrawFinished,通知 wms 可以显示图层了。

终于分析完了,回调一多就容易绕,流下了没有技术的眼泪。

# 总结

  • SurfaceSyncGroup 以树的形式组织在一起。
  • SurfaceSyncGroup 以此往上回调,只有每个节点都调用了markSyncReady 后,才能调用到根节点的 mTransactionReadyConsumer 回调,进一步调用到 reportDrawFinished 方法,通知 wms 显示图层。

20241106003419

原图链接:https://boardmix.cn/app/share/CAE.CMLx1wwgASoQXfKYHfTZha6HKulTcIApEjAGQAE/hxtUlY。

# 参考资料